package cn.uidcc.websocket.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import javax.websocket.ContainerProvider;
import javax.websocket.WebSocketContainer;
import java.net.URI;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by user on 2021/6/26.
 */
@Configuration
@Order(1)
public class WebSocketConfig implements ApplicationRunner {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketConfig.class);

    private static Boolean isOk;

    private static WebSocketContainer container = ContainerProvider.getWebSocketContainer();

    private WebSocketClient client;

    /**
     * 定义定时任务线程
     */
    private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

    @Value("${springboot.websocket.uri}")
    private String uri;

    @Value("${springboot.websocket.ip}")
    private String ip;

    /*@Autowired
    public void setMessageService(RedisUtils redisUtils) {
        WebSocketClient.redisUtils = redisUtils;
    }*/

    /**
     * <run>
     *
     * @param args args
     * @throws
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        logger.info("[WebSocketConfig] web socket init start.");

        // websocket客户端初始化
        wsClientInit();
    }

    /**
     * <websocket客户端初始化>
     *
     * @throws
     */
    public void wsClientInit() {
        logger.info("[WebSocketConfig] start to wsClientInit");
        try {
            client = new WebSocketClient();
            WebSocketClient.beforeInit();
            container.connectToServer(client, new URI(uri + UUID.randomUUID().toString().replaceAll("-", "")));

            isOk = true;
        } catch (Exception e) {
            isOk = false;
            logger.error("error, cause: ", e);
        }

        /**
         *  参数：1、任务体
         *        2、首次执行的延时时间
         *        3、任务执行间隔
         *        4、间隔时间单位
         **/
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                //心跳检测 断线重连
                heartbeatCheck();
            }
        }, 1, 30, TimeUnit.SECONDS);

        logger.info("[WebSocketConfig] end to wsClientInit");
    }

    /**
     * <心跳检测 断线重连>
     *
     * @throws
     */
    private void heartbeatCheck()
    {
        logger.info("[WebSocketConfig] start to heartbeatCheck");
        if (isOk != null && isOk) {
            try {
                client.send("ping " + ip);
            } catch (Exception e) {
                isOk = false;
            }
        } else {
            // 系统连接失败进行重试
            logger.warn("系统连接失败，正在重连...");
            try {
                client.send("ping " + ip);
                logger.warn("系统重连成功！");
                isOk = true;
            } catch (Exception e) {
                try {
                    client = new WebSocketClient();
                    container.connectToServer(client, new URI(uri + UUID.randomUUID().toString().replaceAll("-", "")));

                    isOk = true;
                }
                catch (Exception e1) {
                    isOk = false;
                }

                if (isOk != null && isOk) {
                    logger.warn("系统重连成功！");
                }
            }
        }
    }
}